package com.wdciti.sccp.iot.springvertx.protocols.tcp;

import com.wdciti.sccp.iot.springvertx.EndPointVerticle;
import com.wdciti.sccp.iot.springvertx.protocols.tcp.ext.FrameNetClientImpl;
import io.netty.handler.codec.ByteToMessageDecoder;
import io.vertx.core.Context;
import io.vertx.core.Vertx;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.impl.CloseFuture;
import io.vertx.core.impl.VertxInternal;
import io.vertx.core.net.NetClient;
import io.vertx.core.net.NetClientOptions;
import io.vertx.core.net.SocketAddress;
import io.vertx.core.net.impl.NetClientImpl;
import lombok.extern.slf4j.Slf4j;


/**
 * @author by early
 */
@Slf4j
public class SimpleTcpClientVerticle extends EndPointVerticle {

    private final NetClientOptions netClientOptions = new NetClientOptions();
    private NetClient netClient;
    private SocketAddress remote;
    private boolean printHex;

    public SimpleTcpClientVerticle() {

    }

    public SimpleTcpClientVerticle(ByteToMessageDecoder decoder) {
        this.decoder = decoder;
    }

    @Override
    public void init(Vertx vertx, Context context) {
        super.init(vertx, context);
        String host = config().getString("host");
        int port = config().getInteger("port");
        this.printHex = config().getBoolean("printHex", false);
        this.remote = SocketAddress.inetSocketAddress(port, host);
        this.netClient = createNetClient((VertxInternal) vertx);
    }

    private NetClient createNetClient(VertxInternal vertx) {
        CloseFuture closeFuture = vertx.closeFuture();
        NetClientImpl client = new FrameNetClientImpl(vertx, netClientOptions, closeFuture, decoder);
        closeFuture.add(client);
        return client;
    }

    @Override
    public void start() {
        netClient.connect(remote)
                .onSuccess(new NetHandler(vertx.eventBus(), this.busAddr, this.codecName, this.printHex))
                .andThen(hdl -> vertx.eventBus().publish(this.busAddr + EndPointVerticle.READY, Buffer.buffer("ready")))
                .onFailure(Throwable::printStackTrace);

//        netClient.connect(remote).onSuccess(sock->{
//            sock.handler(buf->{
//                String s = HexUtils.toHexString(buf.getBytes());
//                log.info(s);
//            });
//        });
        //发布socket就绪消息
//        vertx.setTimer(500, hd -> {
//            MultiMap map = EndpointHeadersAdaptor.emptyHeaders().addBusAddr(this.busAddr, READY).headers();
//            DeliveryOptions readyOpt = new DeliveryOptions().setHeaders(map);
//            vertx.eventBus().publish(this.busAddr + READY, Buffer.buffer().appendInt(0x0f), readyOpt);
//        });

    }

    @Override
    public void stop() {
        this.netClient.close(hd -> {
            if (hd.succeeded()) {
                log.info("netClient stopped! ::" + hd.result());
            } else {
                log.warn("netClient stop failed!" + hd.cause().getMessage(), hd.cause());
            }
        });
    }

}
